package com.szsh.aiot.hsm.utils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * json字符串与对象互转
 * 
 * @author luohuawuyin
 *
 */
@Component
public class JsonConvert implements ApplicationContextAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(JsonConvert.class);
    private static ObjectMapper MAPPER;

    static {
        MAPPER = new ObjectMapper();

        // 允许将JSON中的空字符串（""）作为null值绑定到一个POJO或者Map或者Collection集合对象
        MAPPER.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        // 忽略未知属性
        MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 不序列化 null 值
        MAPPER.setSerializationInclusion(Include.NON_NULL);
    }

    private JsonConvert() {

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 从spring中获取对象
        ObjectMapper objectMapper = applicationContext.getBean(ObjectMapper.class);
        if (null != objectMapper) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("从spring中获取ObjectMapper成功");
            }
            // 拷贝 不影响原始的
            MAPPER = objectMapper.copy();

            // 不序列化 null 值
            MAPPER.setSerializationInclusion(Include.NON_NULL);
        }
    }

    /**
     * json字符串转成对象
     * @param cname  要转的对象类型
     * @param json  json字符串
     * @return null:转换失败;<br>
     *         否则返回转换后的数据
     * @param <T> 模板类
     */
    public static <T> T str2Object(Class<T> cname, String json) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        try {
            return MAPPER.readValue(json, cname);
        } catch (Exception e) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("json字符串转换失败！", e);
            }
        }
        return null;
    }

    /**
     * json字符串转成对象列表
     * @param cname  要转的对象类型
     * @param json   json字符串
     * @return null:转换失败;<br>
     *         否则返回转换后的数据
     * @param <T> 模板类
     */
    public static <T> List<T> str2List(Class<T> cname, String json) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        if (!(json.startsWith("[") && json.endsWith("]"))) {
            return null;
        }
        try {
            JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class,
                    cname);
            return MAPPER.readValue(json, javaType);
        } catch (Exception e) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("json字符串转换失败！", e);
            }
        }
        return null;
    }

    /**
     * 对象转成字符串
     * @param obj 需要转的对象
     * @return null:系统异常;<br>
     *         否则返回转换后的字符串
     */
    public static String object2str(Object obj) {
        try {
            return MAPPER.writeValueAsString(obj);
        } catch (Exception e) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("对象转json字符串失败！", e);
            }
        }
        return null;
    }
}
